ARD2  RC2
Airbag Reference Demonstrator using MPC5604P
UTILS.c
Go to the documentation of this file.
00001 
00018 #include "derivative.h"
00019 #include "utils.h"
00020 #include <limits.h>
00021 /*
00022  ******************************************************************************
00023  * constants
00024  ******************************************************************************
00025  */
00026 const uint8_t cau8OddParityTable[] = 
00027 {
00028   /* This table gives the opposite of the calculated parity - it's what      */
00029   /* must be added in order to give the correct parity bit.                  */
00030   /* 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F */
00031      0u, 1u, 1u, 0u, 1u, 0u, 0u, 1u, 1u, 0u, 0u, 1u, 0u, 1u, 1u, 0u
00032     /* 1u, 0u, 0u, 1u, 0u, 1u, 1u, 0u, 0u, 1u, 1u, 0u, 1u, 0u, 0u, 1u*/
00033 };
00034  /*
00035  ******************************************************************************
00036  * Globals
00037  ******************************************************************************
00038  */
00039 /*
00040  ******************************************************************************
00041  * u8fnCheckOddParity
00042  ******************************************************************************
00043  */
00044 uint8_t u8fnCheckOddParity(uint8_t u8Byte, uint8_t u8ParityPosition)
00045 {
00046   /* LocalVariables */
00047   uint8_t u8ParityLow;
00048   uint8_t u8ParityHigh;
00049   uint8_t u8Parity;
00050   
00051   /* Calculate parity for each nibble in the byte */
00052   u8ParityHigh = cau8OddParityTable[u8Byte >> BITS_IN_NIBBLE];
00053   u8ParityLow  = cau8OddParityTable[u8Byte & 0x0Fu];
00054   
00055   /* Combine both calculations using XOR: */
00056   /* Even and even = Even                 */
00057   /* Odd and odd   = Even                 */
00058   /* Even and odd  = Odd                  */
00059   /* Odd and even  = Odd                  */
00060   u8Parity = (u8ParityHigh ^ u8ParityLow);
00061   
00062   /* If u8Parity is cleared, this means we currently hold even parity. */
00063   if(CLEAR == u8Parity)
00064   {
00065     /* If a bit position is set for it, return u8Byte with its value */
00066     if(CLEAR != u8ParityPosition)
00067     {
00068       u8Parity = (u8Byte | u8ParityPosition);
00069     }
00070     else
00071     {
00072       /* Make u8Parity 1 to signal we need to add one */
00073       u8Parity = TRUE;
00074     }
00075   }
00076   else
00077   {
00078     /* Parity bit is set, meaning the byte is already odd parity */
00079     if(CLEAR != u8ParityPosition)
00080     {
00081       /* Output the message without the parity bit set */
00082       u8Parity = u8Byte;
00083     }
00084     else
00085     {
00086       /* Make u8Parity 0 to signal we don't need to add anything */
00087       u8Parity = CLEAR;
00088     }
00089   }
00090   
00091   return(u8Parity);
00092 }
00093 /*
00094  ******************************************************************************
00095  * u16fnCheckOddParity
00096  ******************************************************************************
00097  */
00098 uint16_t u16fnCheckOddParity(uint16_t u16Word, uint16_t u16ParityPosition)
00099 {
00100   /* LocalVariables */
00101   uint8_t  u8ParityLow;
00102   uint8_t  u8ParityHigh;
00103   uint16_t u16Parity;
00104   
00105   /* Calculate parity for each byte in the word - the result is what we need */
00106   /* to add to the word in order to make it odd parity.                      */
00107   u8ParityHigh = u8fnCheckOddParity((uint8_t)(u16Word >> BITS_IN_BYTE), CLEAR);
00108   u8ParityLow  = u8fnCheckOddParity((uint8_t)u16Word, CLEAR);
00109   
00110   /* Combine both calculations with XNOR                               */
00111   /* Parity bit needed + Parity bit needed = Parity bit needed         */
00112   /* Parity bit needed + Parity bit not needed = Parity bit not needed */
00113   /* Parity bit not needed + Parity bit needed = Parity bit not needed */
00114   /* Parity bit not needed + Parity bit not needed = Parity bit needed */
00115   
00116   u16Parity = !(u8ParityHigh ^ u8ParityLow);
00117   
00118   
00119   /* If a bit position is set for it, return u16Word with its value */
00120   if(CLEAR != u16ParityPosition)
00121   {
00122     if(CLEAR != u16Parity)
00123     {
00124       u16Parity = (u16Word | u16ParityPosition);
00125     }
00126     else
00127     {
00128       u16Parity = u16Word;
00129     }
00130   }
00131   else
00132   {
00133     /* Just Output u16Parity */
00134   }
00135   
00136   return(u16Parity);
00137 }
00138 /*
00139  ******************************************************************************
00140  * u32fnCheckOddParity
00141  ******************************************************************************
00142  */
00143 uint32_t u32fnCheckOddParity(uint32_t u32Word, uint32_t u32ParityPosition)
00144 {
00145   /* LocalVariables */
00146   uint16_t  u16ParityLow;
00147   uint16_t  u16ParityHigh;
00148   uint32_t  u32Parity;
00149   
00150   /* Calculate parity for each byte in the word - the result is what we need */
00151   /* to add to the word in order to make it odd parity.                      */
00152   u16ParityHigh = u16fnCheckOddParity((uint16_t)(u32Word >> BITS_IN_16), CLEAR);
00153   u16ParityLow  = u16fnCheckOddParity((uint16_t)u32Word, CLEAR);
00154   
00155   /* Combine both calculations with XNOR                               */
00156   /* Parity bit needed + Parity bit needed = Parity bit needed         */
00157   /* Parity bit needed + Parity bit not needed = Parity bit not needed */
00158   /* Parity bit not needed + Parity bit needed = Parity bit not needed */
00159   /* Parity bit not needed + Parity bit not needed = Parity bit needed */
00160   
00161   u32Parity = !(u16ParityHigh ^ u16ParityLow);
00162   
00163   
00164   /* If a bit position is set for it, return u32Word with its value */
00165   if(CLEAR != u32ParityPosition)
00166   {
00167     if(CLEAR != u32Parity)
00168     {
00169       u32Parity = (u32Word | u32ParityPosition);
00170     }
00171     else
00172     {
00173       u32Parity = u32Word;
00174     }
00175   }
00176   else
00177   {
00178     /* Just Output u32Parity */
00179   }
00180   
00181   return(u32Parity);
00182 }
00183 /*
00184  ******************************************************************************
00185  * u8fnCRC8
00186  ******************************************************************************
00187  */ 
00188 uint8_t u8fnCRC8(const uint8_t* pu8Buffer, uint8_t u8Poly, uint8_t u8MBitsize, \
00189                          uint8_t u8Remainder) 
00190 {
00191   /* Local Variables */
00192         uint8_t u8Value;
00193         uint8_t u8ucBit;
00194         uint8_t u8Count;
00195         uint8_t u8Polynomial;
00196   
00197   u8Polynomial = u8Poly; 
00198   u8Value      = CLEAR; /* Initial value to make MISRA happy */
00199                                    
00200   for (u8Count = CLEAR; u8Count < u8MBitsize; u8Count++)
00201   {
00202     /* End of 8 bits process ? */
00203     if ((u8Count & MSB_MINUS_ONE) == CLEAR) 
00204     {
00205       /* get next buffer value   */
00206       u8Value = pu8Buffer[(u8Count / BITS_IN_BYTE)];
00207     }
00208     else
00209     {
00210       /* Do nothing */ 
00211     }
00212   
00213     u8ucBit = u8Value ^ u8Remainder;
00214     u8Remainder = ((uint8_t)(u8Remainder << 1u));
00215   
00216     /* MSB CRC bit <> MSB Value bit ? */
00217     if(u8ucBit & MSB_8_BITS) 
00218     { 
00219       u8Remainder ^= u8Polynomial;
00220     }
00221     else
00222     {
00223       /* Do nothing */
00224     }
00225     u8Value = ((uint8_t)(u8Value << 1u));
00226   }
00227   
00228   return(u8Remainder);
00229 }
00230 /*
00231  ******************************************************************************
00232  * vfnHexToASCII
00233  ******************************************************************************
00234  */
00235 void vfnASCIIByteToHex(uint8_t* pu8Source, uint8_t* pu8Target, 
00236                        uint16_t u16NOfBytes)
00237 {
00238   for(; u16NOfBytes > CLEAR; u16NOfBytes--)
00239   {
00240     /* Start with the upper nibble */
00241     *pu8Target = u8fnUnitASCIIToHex(*pu8Source);
00242     /* Increment Target index */
00243     pu8Target++;
00244     pu8Source++;
00245   }
00246   
00247   return;
00248 }
00249 /*
00250  ******************************************************************************
00251  * u8fnUnitASCIIToHex
00252  ******************************************************************************
00253  */
00254 static uint8_t u8fnUnitASCIIToHex(const uint8_t u8ASCIIData)
00255 {
00256   uint8_t u8Offset;
00257   
00258   u8Offset = CLEAR;
00259   
00260   if((u8ASCIIData >= 'A') & (u8ASCIIData <= 'Z'))
00261   {
00262     u8Offset = ('A' - (uint8_t)0x0Au);
00263   }
00264   else if((u8ASCIIData >= 'a') & (u8ASCIIData <= 'z'))
00265   {
00266     u8Offset = ('a' - (uint8_t)0x0Au);
00267   }
00268   else if((u8ASCIIData >= '0') & (u8ASCIIData <= '9'))
00269   {
00270     u8Offset = '0';
00271   }
00272   else
00273   {
00274     /* Keep the value as it is */
00275   }
00276   
00277   return(u8ASCIIData - u8Offset);
00278 }
00279 /*
00280  ******************************************************************************
00281  * vfnHexToASCIIMaskToList
00282  ******************************************************************************
00283  */
00284 void vfnHexToASCIIMaskToList(const uint16_t cu16MaskList,
00285                              uint8_t* pau8DataArray,
00286                              uint16_t* pu16Index,
00287                              const uint16_t cu16Mask)
00288 {
00289   uint8_t u8Counter;
00290   
00291   u8Counter = CLEAR;
00292   
00293   for(u8Counter = 1u; u8Counter < 16; u8Counter++)
00294   {
00295     if(cu16Mask & (BIT0 << u8Counter))
00296     {
00297       break;
00298     }
00299     else
00300     {
00301       /* loop */
00302     }
00303   }
00304   
00305   if(cu16MaskList & cu16Mask)
00306   {
00307     pau8DataArray[(*pu16Index)++] = u8fnUnitHexToASCII(u8Counter);
00308     *(pau8DataArray + (*pu16Index)++) = ',';
00309     *(pau8DataArray + (*pu16Index)++) = ' ';
00310   }
00311   else
00312   {
00313     /* Nothing */
00314   }
00315   
00316   return;
00317 }
00318 /*
00319  ******************************************************************************
00320  * vfnHexToASCII
00321  ******************************************************************************
00322  */
00323 void vfnHexToASCII(uint8_t* pu8Source, uint8_t* pu8Target, \
00324                           uint16_t u16NOfBytes)
00325 {
00326   for(; u16NOfBytes > CLEAR; u16NOfBytes--)
00327   {
00328     /* Start with the upper nibble */
00329     *pu8Target = u8fnUnitHexToASCII(*pu8Source >> BITS_IN_NIBBLE);
00330     /* Increment Target index */
00331     pu8Target++;
00332     
00333     /* Continue with the lower nibble */
00334     *pu8Target = u8fnUnitHexToASCII(*pu8Source & 0x0Fu);
00335     /* Increment both indeces */
00336     pu8Target++;
00337     pu8Source++;
00338   }
00339   
00340   return;
00341 }
00342 /*
00343  ******************************************************************************
00344  * u8fnUnitHexToASCII
00345  ******************************************************************************
00346  */
00347 static uint8_t u8fnUnitHexToASCII(uint8_t u8HexData)
00348 {
00349   /* Declare local variables */
00350   uint8_t u8ASCII;
00351   
00352   /* Init local variables */
00353   u8ASCII = CLEAR;
00354   
00355   /* Only look at lower nibble */
00356   u8HexData &= 0x0F;
00357   
00358   /* Translate */
00359   if (u8HexData < 0x0A)
00360   {
00361     u8ASCII = (uint8_t)(u8HexData + '0');
00362   }
00363   else
00364   {
00365     u8ASCII = (uint8_t)((u8HexData - 0x0Au) + 'A');
00366   }
00367   
00368   return (u8ASCII);
00369 }
00370 /*
00371  ******************************************************************************
00372  * vfnCopyArray
00373  ******************************************************************************
00374  */
00375 void vfnCopyArray(uint8_t* pu8Source, uint8_t* pu8Target, \
00376                           uint16_t u16NOfBytes)
00377 {
00378   for(; u16NOfBytes > CLEAR; u16NOfBytes--)
00379   {
00380     /* Start with the upper nibble */
00381     *pu8Target = *pu8Source;
00382     /* Increment Target index + Source */
00383     pu8Target++;
00384     pu8Source++;
00385   }
00386   
00387   return;
00388 }
00389 /*
00390  ******************************************************************************
00391  * Function:          u16fnMaxU16DeltaInArray
00392  *****************************************************************************/
00393 uint16_t u16fnMaxU16DeltaInArray(const uint16_t* au16Array, uint8_t u8ArraySize)
00394 {
00395   /* Declare Local Variables */
00396   uint16_t u16Max;
00397   uint16_t u16Min;
00398   
00399   /* Init local variables */
00400   u16Max = CLEAR;
00401   u16Min = USHRT_MAX;
00402   
00403   /* Loop from last location to the second one (ignores the first one) */
00404   for(--u8ArraySize; u8ArraySize != UCHAR_MAX; u8ArraySize--)
00405   {
00406     /* Search for Array Max */
00407     if(u16Max < au16Array[u8ArraySize])
00408     {
00409       u16Max = au16Array[u8ArraySize];
00410     }
00411     else
00412     {
00413       /* Do nothing */
00414     }
00415     
00416     /* Search for Array Min */
00417     if(u16Min > au16Array[u8ArraySize])
00418     {
00419       u16Min = au16Array[u8ArraySize];
00420     }
00421     else
00422     {
00423       /* Do nothing */
00424     }
00425   }/* End for loop */
00426     
00427   /* Find Max Delta and return it */
00428   return (u16Max - u16Min);
00429 }
00430 /*
00431  ******************************************************************************
00432  * Function:          u32fnDiffAbsoluteValue
00433  *****************************************************************************/
00434 uint32_t u32fnDiffAbsoluteValue(uint32_t au32Value1, uint32_t au32Value2)
00435 {
00436   /* Declare Local Variables */
00437   uint32_t u32Result;
00438   
00439   if(au32Value1 > au32Value2)
00440   {
00441     u32Result = au32Value1 - au32Value2;
00442   }
00443   else
00444   {
00445     u32Result = au32Value2 - au32Value1;
00446   }
00447     
00448   /* Return Absolute Value of the difference */
00449   return (u32Result);
00450 }
00451 /*
00452  ******************************************************************************
00453  *
00454  *  End of file.
00455  *
00456  ******************************************************************************
00457  */